﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SLAU
{
    public class SLAU
    {
        private Matrix coeffs;
        private Vector free;
        private Vector start_vector;

        public Vector StartVector
        {
            get { return start_vector; }
            set { start_vector = value; }
        }

        public Matrix Coefficients
        {
            get
            {
                return coeffs;
            }
        }

        public Vector Free
        {
            get
            {
                return free;
            }
        }

        public int EquationsCount
        {
            get
            {
                return free.Length;
            }
        }

        public SLAU(Matrix coeffs, Vector free, Vector start_vector)
        {
            if (coeffs.GetDimensions(0) != free.Length || coeffs.GetDimensions(0) != start_vector.Length)
            {
                throw new ArgumentException("Dimesions of matrix and free vector are not equal");
            }
            this.coeffs = coeffs;
            this.free = free;
            this.start_vector = start_vector;
        }

        public SLAU(Matrix coeffs, Vector free)
        {
            if (coeffs.GetDimensions(0) != free.Length)
            {
                throw new ArgumentException("Dimesions of matrix and free vector are not equal");
            }
            this.coeffs = coeffs;
            this.free = free;
            this.start_vector = new Vector(free);
        }

        public bool CheckConvergence()
        {
            int n = this.Coefficients.GetDimensions(0);
            double sum = 0.0;

            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    sum += this.Coefficients[i, j] * this.Coefficients[i, j];
                }
            }
            if (Math.Sqrt(Math.Abs(sum)) > 1)
            {
                return false;
            }
            return true;
        }

        public void Normalize()
        {
            int RowCount = this.Coefficients.GetDimensions(0);

            double[,] newCoeff = new double[RowCount, RowCount];
            double[] newFree = new double[RowCount];

            for (var i = 0; i < RowCount; i++)
            {
                for (var j = 0; j < RowCount; j++)
                {
                    if (i == j)
                    {
                        newCoeff[i, j] = 0;
                    }
                    else
                    {
                        newCoeff[i, j] = -this.Coefficients[i, j] / this.Coefficients[i, i];
                    }
                }
                newFree[i] = this.free[i] / this.Coefficients[i, i];
            }
            this.Coefficients.Elements = newCoeff;
            this.Free.Elements = newFree;
        }
    }
}
